# -*_ codeing=utf-8 -*-
# @Time: 2025/10/27 13:36
# @Author: foxhuty
# @File: models.py
# @Software: PyCharm
# @Based on python 3.10
import enum
from datetime import date
from decimal import Decimal
from typing import List, Optional

from sqlalchemy import String, DECIMAL, Boolean, func, ForeignKey, Table, Column
from sqlalchemy.orm import Mapped, mapped_column, sessionmaker, relationship
from sqlalchemy_notes.db_main import BaseModel, engine


class SexValue(enum.Enum):
    """通过枚举，可以给一些属性(字段)设置预设值"""
    MALE = '男'
    FEMALE = '女'


class Student(BaseModel):
    """ 学生的模型类"""
    __tablename__ = "tb_students"
    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    name: Mapped[str] = mapped_column(String(40),
                                      name="student_name",
                                      nullable=False, unique=True)
    # 10总位数，2小数位数
    salary: Mapped[Decimal] = mapped_column(DECIMAL(10, 2),
                                            nullable=True,
                                            comment='工资及津贴')
    bonus: Mapped[int] = mapped_column(default=0, comment='奖金')
    gender: Mapped[SexValue]
    entry_date: Mapped[date] = mapped_column(insert_default=func.now())
    is_leave: Mapped[bool] = mapped_column(Boolean, default=False, comment='是否离职')
    # 与部门表关联的外键
    dept_id: Mapped[Optional[int]] = mapped_column(ForeignKey('tb_departments.id'), nullable=True)
    # 定义一个关联属性：一个员工所在的部门
    dept: Mapped[Optional['Department']] = relationship(back_populates='student_list')
    id_card: Mapped[Optional['IdCard']] = relationship(back_populates='stu')

    def __str__(self):
        return f'{self.name},{self.salary},{self.bonus},{self.gender.value},{self.entry_date},{self.create_time}'


class Department(BaseModel):
    __tablename__ = "tb_departments"
    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    name: Mapped[str] = mapped_column(String(20), name="department_name", nullable=False, unique=True)
    city: Mapped[str] = mapped_column(String(50))
    #  定义关联属性（不是必须的）：一个部门的所有员工
    student_list: Mapped[List['Student']] = relationship(back_populates='dept')
    # 定义一个外键，关联父机构
    pid: Mapped[Optional[int]] = mapped_column(ForeignKey('tb_departments.id'), nullable=True)
    # 定义一个关联属性
    children: Mapped[List['Department']] = relationship(back_populates='parent')
    # 定义一个关联属性
    parent: Mapped[Optional['Department']] = relationship(back_populates='children', remote_side=[id])
    def __str__(self):
        return f'{self.name},{self.city},{self.student_list},{self.pid},{self.children}'


class IdCard(BaseModel):
    __tablename__ = "tb_id_card"
    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    card_number: Mapped[str] = mapped_column(String(18), unique=True, nullable=False)
    origin: Mapped[Optional[str]] = mapped_column(String(50), nullable=True)
    student_id: Mapped[int] = mapped_column(ForeignKey('tb_students.id'), nullable=True)
    # 一对一
    stu: Mapped['Student'] = relationship(single_parent=True,back_populates='id_card')
    def __str__(self):
        return f'{self.id},{self.card_number},{self.origin},{self.student_id}'

# 多对多的中间表
middle_table=Table(
    'tb_user_roles',
    BaseModel.metadata,
    Column('user_id', ForeignKey('tb_users.id'),primary_key=True),
    Column('role_id', ForeignKey('tb_role_players.id'),primary_key=True) #联合主健
)
class Users(BaseModel):
    __tablename__ = "tb_users"
    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    username: Mapped[str] = mapped_column(String(50), nullable=False, unique=True, comment='用户名')
    password: Mapped[str] = mapped_column(String(20), nullable=False)
    #多对多的关联属性
    roles: Mapped[Optional[List['RolePlayers']]] = relationship(secondary=middle_table,back_populates='users')


class RolePlayers(BaseModel):
    __tablename__ = "tb_role_players"
    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    role_name: Mapped[str] = mapped_column(String(50), nullable=False)
    # 多对多的关联属性
    users: Mapped[Optional[List['Users']]] = relationship(secondary=middle_table, back_populates='roles')


# if __name__ == '__main__':
#     BaseModel.metadata.create_all(engine)
